/**
 * MongoDB 集成中间件
 * 将MongoDB功能集成到现有路由中
 */

import { Request, Response, NextFunction } from 'express';
import { connectMongoDB } from '../config/mongodb';
import { mongoDBService } from '../services/mongodb-service';

// 扩展Request接口以包含MongoDB服务
declare global {
  namespace Express {
    interface Request {
      mongodb?: typeof mongoDBService;
    }
  }
}

/**
 * MongoDB连接中间件
 * 确保MongoDB已连接并将服务注入到请求对象中
 */
export const mongoDBMiddleware = async (req: Request, res: Response, next: NextFunction) => {
  try {
    // 确保MongoDB已连接
    await connectMongoDB();
    
    // 将MongoDB服务注入到请求对象中
    req.mongodb = mongoDBService;
    
    next();
  } catch (error) {
    console.error('[MongoDB中间件] 连接失败:', error);
    next(); // 继续执行，不阻塞现有功能
  }
};

/**
 * 日志记录中间件
 * 自动记录API请求日志到MongoDB
 */
export const mongoDBLogger = (req: Request, res: Response, next: NextFunction) => {
  // 保存原始的res.json方法
  const originalJson = res.json;
  
  // 重写res.json方法以捕获响应数据
  res.json = function(body: any) {
    // 异步记录日志，不影响响应速度
    setImmediate(async () => {
      try {
        if (req.mongodb) {
          await req.mongodb.logAction({
            userId: (req as any).user?.id || undefined,
            action: `${req.method} ${req.path}`,
            module: req.path.split('/')[2] || 'unknown', // 从路径提取模块名
            level: res.statusCode >= 400 ? 'error' : 'info',
            message: `${req.method} ${req.path} - ${res.statusCode}`,
            ipAddress: req.ip,
            userAgent: req.get('User-Agent'),
            requestData: req.method !== 'GET' ? req.body : undefined,
            responseData: res.statusCode >= 400 ? body : undefined
          });
        }
      } catch (error) {
        console.error('[MongoDB日志] 记录失败:', error);
      }
    });
    
    // 调用原始的json方法
    return originalJson.call(this, body);
  };
  
  next();
};

/**
 * 根据路径判断OCR类型
 */
const determineOCRType = (path: string): 'general' | 'medical_id' | 'drug_info' | 'document' => {
  if (path.includes('medical') || path.includes('doctor')) return 'medical_id';
  if (path.includes('drug')) return 'drug_info';
  if (path.includes('document')) return 'document';
  return 'general';
};

/**
 * OCR记录增强中间件
 * 为OCR路由添加MongoDB记录功能
 */
export const ocrRecordMiddleware = (req: Request, res: Response, next: NextFunction) => {
  // 保存原始的res.json方法
  const originalJson = res.json;
  
  res.json = function(body: any) {
    // 调试信息
    console.log('[OCR中间件] 检查条件:', {
      path: req.path,
      pathMatches: req.path.includes('/ocr/') || req.path.includes('/api/ocr/'),
      success: body.success,
      hasMongoDB: !!req.mongodb
    });
    
    // 如果是OCR识别成功的响应，记录到MongoDB
    if ((req.path.includes('/ocr/') || req.path.includes('/api/ocr/')) && body.success && req.mongodb) {
      console.log('[OCR中间件] 准备保存记录 - 路径:', req.path);
      setImmediate(async () => {
        try {
          const userId = (req as any).user?.id || (req as any).user?.userId || 'anonymous';
          const imageUrl = (req as any).file?.path || req.body.imageUrl || 'unknown';
          
          // 获取处理时间
          const processingTime = body.data?.processingTime || 
                               (res as any).processingTime || 
                               0;
          
          // 准备识别结果数据
          const recognitionResult: any = {
            success: body.success,
            text: body.data?.text || body.text || '',
            confidence: body.data?.confidence || body.confidence || 0,
            words: body.data?.words || body.words || []
          };
          
          // 如果是药品识别，添加药品信息
          if (body.data?.drugInfo) {
            recognitionResult.drugInfo = body.data.drugInfo;
          }
          
          // 如果有识别模式信息
          if (body.data?.recognitionMode) {
            recognitionResult.recognitionMode = body.data.recognitionMode;
          }
          
          // 如果有服务使用信息
          if (body.data?.serviceUsed) {
            recognitionResult.serviceUsed = body.data.serviceUsed;
          }
          
          await req.mongodb!.saveOCRRecord({
            userId,
            imageUrl,
            ocrType: determineOCRType(req.path),
            serviceType: body.data?.serviceUsed || body.serviceType || 'tesseract',
            recognitionResult,
            processingTime,
            metadata: {
              originalFileName: (req as any).file?.originalname,
              fileSize: (req as any).file?.size,
              userAgent: req.get('User-Agent'),
              ip: req.ip || req.connection.remoteAddress
            }
          });
          
          console.log('[OCR记录] 保存成功:', {
            userId,
            ocrType: determineOCRType(req.path),
            success: body.success,
            confidence: recognitionResult.confidence
          });
        } catch (error) {
          console.error('[OCR记录] 保存失败:', error);
        }
      });
    }
    
    return originalJson.call(this, body);
  };
  
  next();
};

/**
 * 用户同步中间件
 * 在用户操作时同步到MongoDB
 */
export const userSyncMiddleware = (req: Request, res: Response, next: NextFunction) => {
  const originalJson = res.json;
  
  res.json = function(body: any) {
    // 如果是用户相关的成功操作，同步到MongoDB
    if ((req.path.includes('/auth/') || req.path.includes('/user/')) && body.success && req.mongodb) {
      setImmediate(async () => {
        try {
          // 登录成功时更新最后登录时间
          if (req.path.includes('/login') && body.user) {
            await req.mongodb!.updateUser(body.user.id, {
              lastLoginAt: new Date()
            } as any);
          }
          
          // 注册成功时创建用户记录
          if (req.path.includes('/register') && body.user) {
            const existingUser = await req.mongodb!.getUserById(body.user.id);
            if (!existingUser) {
              await req.mongodb!.createUser({
                userId: body.user.id,
                username: body.user.username,
                email: body.user.email,
                password: body.user.password, // 已经加密
                role: body.user.role,
                createdAt: new Date()
              } as any);
            }
          }
          
          // 人脸识别成功时更新人脸数据
          if (req.path.includes('/face/') && req.path.includes('/enroll') && body.success) {
            const userId = (req as any).user?.id || req.body.userId;
            if (userId && req.body.faceHash) {
              await req.mongodb!.updateUserFaceData(userId, {
                hash: req.body.faceHash,
                timestamp: new Date()
              });
            }
          }
        } catch (error) {
          console.error('[用户同步] 同步失败:', error);
        }
      });
    }
    
    return originalJson.call(this, body);
  };
  
  next();
};